import BezierEasing from 'bezier-easing'

//前1/3加速
//中1/3匀速
//后1/3减速
export class EasingLinear {
  constructor(options) {
    let times = options.times || [1, 1, 1]
    let total = times.reduce((memo, item) => memo + item)
    let timesPercent = times.map((res) => res / total)
    let { a1, a2 } = this.calA(timesPercent)
    this.a1 = a1
    this.a2 = a2
    this.timesPercent = timesPercent
  }
  easing(nowTimePercent) {
    let [x0, x1, x2] = this.timesPercent
    let p = 0
    let { a1, a2 } = this
    if (nowTimePercent < x0) {
      p = (1 / 2) * a1 * Math.pow(nowTimePercent, 2)
    } else if (nowTimePercent >= x0 && nowTimePercent <= x1 + x0) {
      let p1 = (1 / 2) * a1 * Math.pow(x0, 2)
      let v = a1 * x0
      let p2 = (nowTimePercent - x0) * v
      p = p1 + p2
    } else {
      let p1 = (1 / 2) * a1 * Math.pow(x0, 2)
      let v = a1 * x0
      let p2 = x1 * v
      let t = nowTimePercent - x1 - x0
      //这里其实可以嵌套任意的easing再进行组合
      //t = BezierEasing(0, 1, 1, 1)(t / x2) * x2
      //这里先快再慢还是有问题
      let p3 = v * t - (1 / 2) * a2 * Math.pow(t, 2)
      p = p1 + p2 + p3
    }
    return p
  }
  calA(times_percent) {
    //(上 + 下) * 高 / 2
    //高就是v
    //利用了梯形原理
    let v = 2 / (times_percent[1] + 1)
    let a1 = v / times_percent[0]
    let a2 = v / times_percent[2]
    return {
      a1,
      a2
    }
  }
}
export default class Lottery {
  constructor(options) {
    this.turn = options.turn
    this.startIndex = options.startIndex
    this.total = options.total
    this.time = options.time
    //cubic-bezier(.36,.72,.62,.55)
    //this.easing = {
    //easing : BezierEasing(0.36, 0.72, 0, 0.99)
    //}
    this.easing = new EasingLinear({
      times: [1, 1, 2]
    })
    this.endIndex = 0
    this.nowIndex = this.startIndex
  }
  calSteps() {
    let { total, startIndex, turn } = this
    let endIndex = Math.floor(Math.random() * total)
    let diff = endIndex - startIndex
    diff = diff < 0 ? diff + total : diff
    let steps = turn * total + diff
    this.endIndex = endIndex
    //console.log(`endIndex`, endIndex)
    return steps
  }
  start(cb) {
    let steps = this.calSteps()
    this.steps = steps
    this.animate(cb, this.time)
  }
  animate(cb, time) {
    this.sTime = +new Date()
    this.step(cb, time)
  }
  step(cb, time) {
    requestAnimationFrame((res) => {
      let eTime = +new Date()
      let diff = eTime - this.sTime
      if (diff < time * 1e3) {
        let percent = this.easing.easing(diff / (time * 1e3))
        let nowIndex = (Math.floor(percent * this.steps) + this.startIndex) % this.total
        cb(nowIndex)
        this.step(cb, time)
      } else {
        let nowIndex = this.endIndex
        this.startIndex = nowIndex
        this.nowIndex = nowIndex
        cb(nowIndex)
      }
    })
  }
}
